home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / cc21d.zip / CC.C next >
C/C++ Source or Header  |  1994-03-08  |  12KB  |  278 lines

  1. /*-------------------------------------------------------------------------*/
  2. /* Program:    CC      .C                                                  */
  3. /* Purpose:    Processes ASA carriage control characters in a file.        */
  4. /* Notes:      Compiles under Borland C++, v3.1. Should work on any        */
  5. /*                machine running DOS, v2.xx or higher.                    */
  6. /* Status:     Source released into the public domain. If you find this    */
  7. /*                program useful, I'd appreciate a postcard.               */
  8. /* Updates:    02-Mar-89, GAT                                              */
  9. /*                - initial version.                                       */
  10. /*             02-May-89, GAT                                              */
  11. /*                - eliminated some start-up code.                         */
  12. /*             03-Dec-89, GAT                                              */
  13. /*                - Improved efficiency of help message display.           */
  14. /*                - Renamed ErrMsg() to write_ErrMsg().                    */
  15. /*                - Now write_ErrMsg adds a period and CR/LF combination.  */
  16. /*             03-Jan-90, GAT                                              */
  17. /*                - Rewrote principal functions.                           */
  18. /*                - Replaced most #defines with enumerations.              */
  19. /*                - Used AT&T's getopt() for program args.                 */
  20. /*                - Separated usage message into its own function.         */
  21. /*                - Tweaked variable storage.                              */
  22. /*                - Eliminated -t option for processing tab characters.    */
  23. /*                - Added headers in case of multiple files.               */
  24. /*             02-Aug-90, GAT                                              */
  25. /*                - Added a CR to output stream before each formfeed.      */
  26. /*                - Used return in main() rather than exit().              */
  27. /*             17-Feb-91, GAT                                              */
  28. /*                - Added copyright message.                               */
  29. /*                - Made use of new TifaWARE library functions.            */
  30. /*             26-Jan-92, GAT, v2.1c                                       */
  31. /*                - A carriage return instead of a linefeed now is output  */
  32. /*                   before a formfeed.                                    */
  33. /*             05-Jul-93, GAT, v2.1d                                       */
  34. /*                - compiled with BCC 3.1.                                 */
  35. /*-------------------------------------------------------------------------*/
  36.  
  37. /*-------------------------------------------------------------------------*/
  38. /* Author:     George A. Theall                                            */
  39. /* SnailMail:  TifaWARE                                                    */
  40. /*             610 South 48th St                                           */
  41. /*             Philadelphia, PA.  19143                                    */
  42. /*             U.S.A.                                                      */
  43. /* E-Mail:     george@tifaware.com                                         */
  44. /*             theall@popmail.tju.edu                                      */
  45. /*             theall@mcneil.sas.upenn.edu                                 */
  46. /*             george.theall@satalink.com                                  */
  47. /*-------------------------------------------------------------------------*/
  48.  
  49. /* Useful type definitions. */
  50. typedef int BOOLEAN;
  51.  
  52. typedef enum {                               /* error classes           */
  53.    err_open,                                 /*    can't open a file    */
  54.    err_read,                                 /*    can't read from file */
  55.    err_write                                 /*    can't write to file  */
  56. } ERR_TYPE;
  57.  
  58. typedef enum {                               /* return codes */
  59.    rc_ok    = 0,
  60.    rc_help  = 1,
  61.    rc_open  = 10,
  62.    rc_read  = 15,
  63.    rc_write = 20
  64. } RC_TYPE;
  65.  
  66. #define FALSE        0
  67. #define TRUE         1
  68.  
  69. #include <assert.h>
  70. #include <ctype.h>                           /* for isdigit() */
  71. #include <dir.h>                             /* for fnsplit(), MAXFILE, etc */
  72. #include <stdarg.h>                          /* for va_arg, etc.. */
  73. #include <stdio.h>
  74. #include <stdlib.h>                          /* for exit() */
  75. #include <string.h>                          /* for strlwr() */
  76. #include "tifa.h"                            /* TifaWARE library routines */
  77.  
  78. char ProgName[MAXFILE];                      /* space for filename */
  79. char *ifn, *ofn;                             /* input/output file names */
  80. static BOOLEAN                               /* flags for various options */
  81.    hFlag = FALSE;                            /*    needs help?            */
  82.  
  83. /* Define the program's error messages. */
  84. /*
  85.  * NB: getopt() itself is responsible for generating the following
  86.  * error messages, which do not appear in the structure below:
  87.  *    ": illegal option -- %c"
  88.  *    ": option requires an argument -- %c"
  89.  */
  90. const static struct {
  91.    ERR_TYPE Type;
  92.    char *Msg;
  93. } Error[] ={
  94.    {err_open,  ": can't open %s"},
  95.    {err_read,  ": can't read from %s; processing halted at line %lu"},
  96.    {err_write, ": can't write to %s; processing halted at line %lu of %s"}
  97. };
  98.  
  99. void _setenvp(void) {};                      /* drop some start-up code */
  100.  
  101.  
  102. /*---  main  --------------------------------------------------------------+
  103. |  Purpose:    Main body of program.                                       |
  104. |  Notes:      none                                                        |
  105. |  Entry:      argc = argument count,                                      |
  106. |              argv = array of argument variables.                         |
  107. |  Exit:       Return code as enumerated by RC_TYPE.                       |
  108. +-------------------------------------------------------------------------*/
  109. int main(int argc, char *argv[])
  110. {
  111.    char ch;
  112.    BOOLEAN hdrs;                             /* need headers? */
  113.    RC_TYPE rc = rc_ok;                       /* program return code */
  114.    FILE *ifp, *ofp;                          /* input/output file pointers */
  115.    void write_usage(void);
  116.    void cc(FILE *, FILE *);
  117.  
  118.    /*
  119.     * Isolate program name to keep error messages neat. This kludge
  120.     * is necessary for DOS v2.xx when argv[0] is NULL.
  121.     */
  122.    fnsplit((*argv == NULL) ? __FILE__ : *argv,  /* TURBO C extension! */   
  123.       NULL, NULL, ProgName, NULL);
  124.    *argv = strlwr(ProgName);                    /* TURBO C extension! */
  125.  
  126.    /* All options must appear before any filenames. */
  127.    while ((ch = getopt(argc, argv, "?")) != EOF)
  128.       switch (ch)
  129.       {
  130.          case '?': hFlag = TRUE; break;      /* help needed or requested */
  131.          default:  ; /* EMPTY */             /* Unreached */
  132.       }
  133.    do
  134.    {
  135.       --argc;
  136.       ++argv;
  137.    } while (--optind);                       /* nb: optind >= 1 in getopt() */
  138.  
  139.    if (hFlag == TRUE)
  140.    {
  141.       write_usage();
  142.       exit(rc_help);
  143.    }
  144.  
  145.    /* Loop thru each file named on commandline. */
  146.    assert(argc >= 0);
  147.    ofp = stdout;                             /* might be changed later */
  148.    ofn = "stdout";
  149.    if (argc == 0)
  150.    {
  151.       ifn = "stdin";
  152.       cc(stdin, ofp);
  153.    }
  154.    else
  155.    {
  156.       hdrs = (argc > 1) ? TRUE : FALSE;      /* headers needed if > 1 file */
  157.       do
  158.       {
  159.          ifn = *argv;
  160.          if ((ifp = fopen(ifn, "r")) == NULL)
  161.          {
  162.             write_errmsg(Error[err_open].Msg, ifn);
  163.             rc = rc_open;
  164.             continue;                        /* skip file; don't abort */
  165.          }
  166.          if (hdrs == TRUE)
  167.             fprintf(ofp, "==> %s <==\n", ifn);
  168.          cc(ifp, ofp);
  169.          fclose(ifp);
  170.       } while (*++argv);
  171.    }
  172.    return rc;
  173. }
  174.  
  175. /*---  write_usage  -------------------------------------------------------+
  176. |  Purpose:    Provides a brief mes